﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CDSB.Indicators.Communication;
using CDSB.Indicators.Model;
using CDSB.Indicators.Comum;
using CDSB.Indicators.Enum;
using System.IO;
using System.Collections;

namespace CDSB.Indicators.Presenter
{
    public class TFSPerformanceIndicator:IDisposable
    {
        private TFSAccess TFSAccess;
        private ITFSPerformanceIndicator View;
        private DateTime StartDate;
        private DateTime FinishDate;
        private List<CDSBScenario> ScenarioList;
        private Boolean HasErrors;

        public TFSPerformanceIndicator(ITFSPerformanceIndicator view) 
        {
            ConfigAccess.teste();
            this.View = view;
            TFSAccess = new TFSAccess("http://utilcorp05:8080");
        }

        public void GeneratePerformanceIndicators(DateTime startDate, DateTime finishDate, bool punctuality, bool configuration, bool changerequest, bool period)
        {
            this.StartDate = startDate;
            this.FinishDate = finishDate;

            this.HasErrors = false;

            if (configuration)
            {
                this.View.ShowStatus(StepMessage.Configuration);
                this.CountCheckinMerge();
            }

            if (changerequest)
            {
                this.View.ShowStatus(StepMessage.Changerequest);
                this.CreateChangeRequestIndicator();
            }

            this.View.ShowStatus(StepMessage.ScenarioList);
            this.GetScenarioCollection();

            this.View.ShowStatus(StepMessage.ScenarioNumber);
            this.GenerateWorkItemNumberIndicator(this.ScenarioList);

            if (punctuality)
            {
                this.View.ShowStatus(StepMessage.Punctuality);
                this.GeneratePunctualityIndicator(this.ScenarioList);
            }

            this.GenerateIndicatorGeneratingFactor();

            this.View.ShowStatus(StepMessage.Quality);
            this.GenerateCDSBQualityIndicator();
            
            this.View.ShowStatus(StepMessage.CodeReview);
            this.GenerateCodeReviewPercent();

            this.View.ShowStatus(StepMessage.CodeProvider);
            this.GenerateCodeProviderIndicator();

            this.View.ShowStatus(StepMessage.Finished);
            this.View.NotifyFinalProcess(this.HasErrors);
        }

        private void GenerateIndicatorGeneratingFactor() 
        { 
            List<Model.CDSBBugGeneratorIndicator> GFactorCollection = new List<CDSBBugGeneratorIndicator>();
            Model.CDSBBugGeneratorIndicator GFactor = null;

            ScenarioList.ForEach(item =>
            {
                if (item.Project != "Suporte 3º Nível")
                {
                    bool addNew = false;

                    GFactor = GFactorCollection.Find(delegate(CDSBBugGeneratorIndicator indicator) { return indicator.ProjectName == item.Project; });

                    if (GFactor == null)
                    {
                        GFactor = new CDSBBugGeneratorIndicator();
                        addNew = true;
                    }

                    GFactor.ProjectName = item.Project;
                    GFactor.Architecture += item.BugsList.Count(delegate(CDSBBug Bug) { return Bug.Gerador == TipoGerador.Arquitetura; });
                    GFactor.Business += item.BugsList.Count(delegate(CDSBBug Bug) { return Bug.Gerador == TipoGerador.Negocio; });
                    GFactor.Developement += item.BugsList.Count(delegate(CDSBBug Bug) { return Bug.Gerador == TipoGerador.Desenvolvimento; });
                    GFactor.Infra += item.BugsList.Count(delegate(CDSBBug Bug) { return Bug.Gerador == TipoGerador.InfraEstrutura; });
                    GFactor.Release += item.BugsList.Count(delegate(CDSBBug Bug) { return Bug.Gerador == TipoGerador.ReleaseManager; });
                    GFactor.UX += item.BugsList.Count(delegate(CDSBBug Bug) { return Bug.Gerador == TipoGerador.UX; });

                    if (addNew) GFactorCollection.Add(GFactor);
                }
            });

            this.View.ShowIndicatorGeneratingFactor(GFactorCollection);
        }

        private void GenerateCDSBQualityIndicator()
        {
            List<CDSBQualityIndicator> QIndicatorCol = new List<CDSBQualityIndicator>();
            CDSBQualityIndicator QIndicator = null;

            ScenarioList.ForEach(item =>
            {
                if (string.IsNullOrEmpty(item.Project))
                {
                    String BugsWhithoutScenario = string.Empty;
                    String TasksWhithoutScenario = string.Empty;

                    item.BugsList.ForEach(itemBug => 
                        {
                            BugsWhithoutScenario += itemBug.ID + Environment.NewLine;
                        });

                    item.TasksList.ForEach(itemTask =>
                        {
                            TasksWhithoutScenario += itemTask.ID + Environment.NewLine;
                        });

                    this.View.ShowWorkItemsWithoutScenario(TasksWhithoutScenario, BugsWhithoutScenario);
                }
                else if (item.Project != "Suporte 3º Nível")
                {
                    bool addNew = false;

                    QIndicator = QIndicatorCol.Find(delegate(CDSBQualityIndicator indicator) { return indicator.ProjectName == item.Project;});

                    if (QIndicator == null)
                    {
                        QIndicator = new CDSBQualityIndicator();
                        addNew = true;
                    }
                    
                    QIndicator.ProjectName = item.Project;
                    QIndicator.NumberScenarios++;
                    QIndicator.NumberOfBugs += item.BugsList.Count(delegate(CDSBBug Bug) { return Bug.Gerador == TipoGerador.Desenvolvimento; });
                    QIndicator.CodeReview += item.TasksList.Count(delegate(CDSBTaskDesenv task) { return task.IsCodeApproved == false && task.IsOldTask == false; });

                    if (addNew) QIndicatorCol.Add(QIndicator);
                }
            });

            this.View.ShowQualityIndicator(QIndicatorCol);
        }

        private void GravarArquivo(string path, string conteudo) 
        {
            StreamWriter W = new StreamWriter(path, false);

            W.Write(conteudo);

            W.Flush();
            W.Close();
            W.Dispose();
        }

        private List<CDSBFactory> GenerateCodeProviderList() 
        {
            string FactoryUnknow = string.Empty;
            string InternalFactory = string.Empty;
            string ExternalFactory = string.Empty;

            List<CDSBFactory> FactoryList = new List<CDSBFactory>();

            ScenarioList.ForEach(itemScenario => {

                if (itemScenario.ID > 0)
                {
                    CDSBFactory Factory = null;
                    DateTime LastTaskDate = DateTime.MinValue;

                    itemScenario.TasksList.ForEach(itemTask =>
                    {
                        if (itemTask.CodeProvider.ToLower() == string.Empty)
                        {
                            HasErrors = true;
                            FactoryUnknow += FactoryUnknow.Length > 0 ? itemTask.ID.ToString() : "," + itemTask.ID.ToString();
                        }
                        else if (!itemTask.IsOldTask)
                        {
                            if (itemTask.CodeProvider.ToLower() == "cdsb")
                            {
                                InternalFactory += InternalFactory.Length > 0 ? "," + itemTask.ID.ToString() : itemTask.ID.ToString();
                            }
                            else
                            {
                                ExternalFactory += ExternalFactory.Length > 0 ? "," + itemTask.ID.ToString() : itemTask.ID.ToString();
                            }

                            Factory = FactoryList.FindFactory(itemTask.CodeProvider);

                            if (Factory != null)
                            {
                                Factory.Tasks.Add(itemTask);
                            }
                            else
                            {
                                Factory = new CDSBFactory();

                                Factory.Factory = itemTask.CodeProvider;
                                Factory.Scenarios = new List<CDSBScenario>();
                                Factory.Tasks = new List<CDSBTaskDesenv>();
                                Factory.Tasks.Add(itemTask);

                                FactoryList.Add(Factory);

                            }

                            LastTaskDate = itemTask.RealizedFinishDate > LastTaskDate ? itemTask.RealizedFinishDate : LastTaskDate;
                        }

                    });

                    CDSBTaskDesenv LastTask = (itemScenario.TasksList.Find(delegate(CDSBTaskDesenv dTask) { return dTask.RealizedFinishDate == LastTaskDate; }));

                    string LastTaskProvider = LastTask != null ? LastTask.CodeProvider : "CDSB";
                    
                    Factory = FactoryList.FindFactory(LastTaskProvider);

                    if (Factory != null) Factory.Scenarios.Add(itemScenario);
                }
            });
            
            this.View.ShowTaskFactoryUnnkow(FactoryUnknow);
            this.View.ShowInternalExternalTasks(InternalFactory, ExternalFactory);

            return FactoryList;
        }

        private void GenerateCodeProviderIndicator()
        {
            List<CDSBFactoryIndicator> FactoryIndicatorList = new List<CDSBFactoryIndicator>();

            this.GenerateCodeProviderList().ForEach(item => {

                CDSBFactoryIndicator FactoryIndicator = new CDSBFactoryIndicator();

                FactoryIndicator.Factory = item.Factory;
                
                FactoryIndicator.BugsCount = Convert.ToDecimal(item.Scenarios.GetTotalOfBugs());
                FactoryIndicator.Scenarios = Convert.ToDecimal(item.Scenarios.Count);

                if (item.Factory.ToLower() == "7comm") 
                {
                    item.Scenarios.ForEach(itemFabrica => {
                        StreamWriter sw = new StreamWriter(@"C:\teste.txt",true);

                        sw.WriteLine(itemFabrica.ID);

                        sw.Flush();
                        sw.Close();
                        sw.Dispose();
                    });
                }

                FactoryIndicator.DevelopedTasks = item.Tasks.Count(delegate(CDSBTaskDesenv taskDesenv) { return taskDesenv.IsOldTask == false; });
                FactoryIndicator.TasksAborted = (from task in item.Tasks where task.State == "Cancelada" && task.IsOldTask == false select task).Count();
                FactoryIndicator.TasksdeliveredLate = (from task in item.Tasks where task.RealizedFinishDate.Date > task.EstimatedFinishDate.Date && task.IsOldTask == false select task).Count();
                FactoryIndicator.TasksDeliveredOnDate = FactoryIndicator.DevelopedTasks - FactoryIndicator.TasksdeliveredLate;

                FactoryIndicator.TasksWithReturnOfCodeReview = (from task in item.Tasks where task.IsCodeApproved == false && task.IsOldTask == false select task).Count();

                FactoryIndicatorList.Add(FactoryIndicator);
            });

            this.View.ShowCodeProviderIndicator(FactoryIndicatorList);
        }

        private void GenerateCodeReviewPercent() 
        {
            decimal Reviewed = ScenarioList.GetTotalTasksReviewed();
            decimal NotApproved = ScenarioList.GetTotalCodeReviewNotApproved();
            decimal CodeReviewPercent = Reviewed > 0 ? Math.Round((NotApproved / Reviewed) * 100, 2): 0;
            this.View.ShowCodeReviewPercent(CodeReviewPercent);
        }

        private void GeneratePunctualityIndicator(List<CDSBScenario> scenarioCollection) 
        {
            CDSBPunctualityIndicator PunctualityIndicator = new CDSBPunctualityIndicator();

            PunctualityIndicator.TotalTasks = scenarioCollection.GetTotalTasks();
            PunctualityIndicator.OutOfDate = scenarioCollection.GetTotalOutOfDateTasks();
            PunctualityIndicator.OnDate = PunctualityIndicator.TotalTasks - PunctualityIndicator.OutOfDate;

            this.View.ShowGeneratePunctualityIndicator(PunctualityIndicator);
        }

        private void GenerateWorkItemNumberIndicator(List<CDSBScenario> scenarioCollection) 
        {
            this.View.ShowTotalWorkItemsIndicator(scenarioCollection.GetTotalWorkItems());
        }

        private void GetScenarioCollection()
        {
            this.ScenarioList = this.TFSAccess.GetScenarioCollectionForDate(this.StartDate, this.FinishDate);
        }

        private void CountCheckinMerge() 
        {
            List<CDSBChangeset> CDSBChangeSetList = TFSAccess.GetAllCDSBChangeSetForDate(this.StartDate, this.FinishDate);

            this.View.ShowChangeSetIndicator(CDSBChangeSetList);
        }

        private void CreateChangeRequestIndicator()
        {
            List<CDSBWorkItem> CDSBWorkItemList = TFSAccess.GetChangeRequestForDate(this.StartDate, this.FinishDate);

            this.View.ShowChangeRequestIndicator(CDSBWorkItemList);
        }

        private void GetHourFromPeriod()
        {
            DateTime.DaysInMonth(this.StartDate.Date.Year, this.StartDate.Date.Month);
        }

        #region IDisposable Members

        public void Dispose()
        {
            TFSAccess.Dispose();
        }

        #endregion
    }
}
